/*
 Base.js, version 1.1a
 Copyright 2006-2009, Dean Edwards
 License: http://www.opensource.org/licenses/mit-license.php
 */
RaisingLight.Core.Object = function()
{
    // dummy
};

RaisingLight.Core.Object.extend = function(_instance, _static)
{ 
	// subclass
    var extend = RaisingLight.Core.Object.prototype.extend;
    
    // build the prototype
    RaisingLight.Core.Object._prototyping = true;
    var proto = new this;
    extend.call(proto, _instance);
    proto.base = function()
    {
        // call this method from any other method to invoke that method's ancestor
    };
    delete RaisingLight.Core.Object._prototyping;
    
    // create the wrapper for the constructor function
    //var constructor = proto.constructor.valueOf(); //-dean
    var constructor = proto.constructor;
    var klass = proto.constructor = function()
    {
        if (!RaisingLight.Core.Object._prototyping) 
        {
            if (this._constructing || this.constructor == klass) 
            { // instantiation
                this._constructing = true;
                constructor.apply(this, arguments);
                delete this._constructing;
            }
            else 
                if (arguments[0] != null) 
                { // casting
                    return (arguments[0].extend || extend).call(arguments[0], proto);
                }
        }
    };
    
    // build the class interface
    klass.ancestor = this;
    klass.extend = this.extend;
    klass.forEach = this.forEach;
    klass.implement = this.implement;
    klass.prototype = proto;
    klass.toString = this.toString;
    klass.valueOf = function(type)
    {
        //return (type == "object") ? klass : constructor; //-dean
        return (type == "object") ? klass : constructor.valueOf();
    };
    extend.call(klass, _static);
    // class initialisation
    if (typeof klass.init == "function") 
        klass.init();
    return klass;
};

RaisingLight.Core.Object.prototype = 
{
    extend: function(source, value)
    {
        if (arguments.length > 1) 
        { // extending with a name/value pair
            var ancestor = this[source];
            if (ancestor && (typeof value == "function") && // overriding a method?
            // the valueOf() comparison is to avoid circular references
            (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&
            /\bbase\b/.test(value)) 
            {
                // get the underlying method
                var method = value.valueOf();
                // override
                value = function()
                {
                    var previous = this.base || RaisingLight.Core.Object.prototype.base;
                    this.base = ancestor;
                    var returnValue = method.apply(this, arguments);
                    this.base = previous;
                    return returnValue;
                };
                // point to the underlying method
                value.valueOf = function(type)
                {
                    return (type == "object") ? value : method;
                };
                value.toString = RaisingLight.Core.Object.toString;
            }
            this[source] = value;
        }
        else 
            if (source) 
            { // extending with an object literal
                var extend = RaisingLight.Core.Object.prototype.extend;
                // if this object has a customised extend method then use it
                if (!RaisingLight.Core.Object._prototyping && typeof this != "function") 
                {
                    extend = this.extend || extend;
                }
                var proto = 
                {
                    toSource: null
                };
                // do the "toString" and other methods manually
                var hidden = ["constructor", "toString", "valueOf"];
                // if we are prototyping then include the constructor
                var i = RaisingLight.Core.Object._prototyping ? 0 : 1;
                while (key = hidden[i++]) 
                {
                    if (source[key] != proto[key]) 
                    {
                        extend.call(this, key, source[key]);
                        
                    }
                }
                // copy each of the source object's properties to this object
                for (var key in source) 
                {
                    if (!proto[key]) 
                        extend.call(this, key, source[key]);
                }
            }
        return this;
    }
};

// initialise
RaisingLight.Core.Object = RaisingLight.Core.Object.extend(
{
    constructor: function()
    {
        this.extend(arguments[0]);
    }
}, 
{
    ancestor: Object,
    version: "1.1",
    
    forEach: function(object, block, context)
    {
        for (var key in object) 
        {
            if (this.prototype[key] === undefined) 
            {
                block.call(context, object[key], key, object);
            }
        }
    },
    
    implement: function()
    {
        for (var i = 0; i < arguments.length; i++) 
        {
            if (typeof arguments[i] == "function") 
            {
                // if it's a function, call it
                arguments[i](this.prototype);
            }
            else 
            {
                // add the interface using the extend method
                this.prototype.extend(arguments[i]);
            }
        }
        return this;
    },
    
    toString: function()
    {
        return String(this.valueOf());
    }
});
